package core

import (
	"github.com/Unixeno/TheMoon/logging"
	"github.com/Unixeno/TheMoon/moon/core/module"
	"github.com/Unixeno/TheMoon/planet/core/context"
	"github.com/Unixeno/TheMoon/planet/gateway"
	"github.com/Unixeno/TheMoon/planet/inspector"
	"github.com/Unixeno/TheMoon/planet/orm"
	"github.com/Unixeno/TheMoon/planet/station"
	"github.com/Unixeno/TheMoon/planet/statistics"
	"github.com/Unixeno/TheMoon/planet/zoner"
	"os"
	"os/signal"
	"syscall"
)

var logger = logging.GetLogger("core")
var modules []module.Module

func Init() {
	logger.Debug("init core")
	modules = []module.Module{
		statistics.GetModule(),
		zoner.GetModule(),
		inspector.GetModule(),
	}
}

func Run() {
	startServe()
	gracefulShutdown()
}

func startServe() {
	logger.Debug("start core")
	err := orm.Init()
	if err != nil {
		logger.WithError(err).Error("failed to init orm")
		os.Exit(1)
	}

	server, err := station.GetServer()
	if err != nil {
		logger.WithError(err).Error("failed to init server")
		os.Exit(1)
	}
	context.InitContext()
	context.RegisterServer(server)
	gateway.Start()

	for _, m := range modules {
		m.Init()
		m.Start()
	}
	go server.Start()
}

func gracefulShutdown() {
	c := make(chan os.Signal)
	signal.Notify(c, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM,
		syscall.SIGQUIT, syscall.SIGILL, syscall.SIGTRAP, syscall.SIGABRT)
	select {
	case s := <-c:
		logger.Infof("get signal %v", s.String())
		context.Cancel()
	}
}
